package com.dingding.order.core.publish.biz.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.UserLogin;
import com.dingding.common.core.beans.Userordert;
import com.dingding.common.core.config.SystemCode;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.user.service.IUserLoginFacade;
import com.dingding.order.code.PublishOrderCodeMsg;
import com.dingding.order.code.order.PublishOrderEnum;
import com.dingding.order.core.publish.biz.IPublishOrderService;
import com.dingding.order.core.publish.biz.ISaveOrderInfoService;
import com.dingding.order.core.publish.dao.IPublishOrderDao;
import com.dingding.order.dto.publish.ReqReleaseOrderDTO;
import com.dingding.order.dto.publish.ResReleaseOrder;

/**
 * @ClassName: PublishOrderServiceImpl
 * @Description: 发布订单操作Service实现类
 * @author YHQ
 * @date 2016年6月3日 上午11:21:50
 */
@Component("publishOrderService")
public class PublishOrderServiceImpl extends AbstractResponse<ResReleaseOrder, ReqReleaseOrderDTO>
		implements IPublishOrderService {

	private Logger log = Logger.getLogger(this.getClass());

	@Resource(name = "saveOrderInfoService")
	private ISaveOrderInfoService saveOrderInfoService;

	@Resource(name = "publishOrderDao")
	private IPublishOrderDao publishOrderDao;

	@Resource(name = "userLoginFacade")
	private IUserLoginFacade userLoginFacade;

	/**
	 * @Title: publishOrder
	 * @Description: 创建订单对象并完成下单
	 * @param reqReleaseOrder
	 *            发布订单请求Bean
	 * @param releaseOrders
	 *            响应Bean
	 * @author YHQ
	 * @return void 返回类型
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String publishOrder(String requestData) {

		ResponseEntity<ResReleaseOrder> response = new ResponseEntity<ResReleaseOrder>();

		ReqReleaseOrderDTO request = super.parseRequestJson(requestData);

		// 判断是否符合发单条件
		boolean flag = this.billingConditions(request, response);

		// 如果不符合发单条件，则终止发单操作
		if (!flag) {
			return super.responseBeanToJson(response);
		}

		// 发布订单-保存订单信息到数据库
		saveOrderInfoService.saveOrderInfo(request, response);

		return super.responseBeanToJson(response);
	}
	
	/**
	 * @Description:发布订单
	 * @param request 发单需要的参数
	 * @author fengshuonan
	 * @return true 发单成功   false 发单失败
	 * @since 2.3.2
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public PublishOrderEnum makeAnOrder(ReqReleaseOrderDTO request){
		
		ResponseEntity<ResReleaseOrder> response = new ResponseEntity<ResReleaseOrder>();
		// 判断是否符合发单条件
		boolean flag = this.billingConditions(request, response);

		// 如果不符合发单条件，则终止发单操作
		if (!flag) {
			return PublishOrderEnum.NOT_MATCH_PUBLISH_CONDITION;
		}

		// 发布订单-保存订单信息到数据库
		saveOrderInfoService.saveOrderInfo(request, response);
		
		if(response.getCode() != 200){
			return PublishOrderEnum.MAKE_ORDER_ERROR;
		}

		return PublishOrderEnum.OK;
	}
	

	/**
	 * 
	 * 发布订单，系统自动发单使用
	 * 
	 * @Title: publishOrder 
	 * @return    设定文件 
	 * @author CHEHAUNBO
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public boolean publishOrder(ReqReleaseOrderDTO reqReleaseOrderDTO) {

		ResponseEntity<ResReleaseOrder> response = new ResponseEntity<ResReleaseOrder>();

		// 判断是否符合发单条件
		boolean flag = this.billingConditions(reqReleaseOrderDTO, response);

		// 如果不符合发单条件，则终止发单操作
		if (!flag) {
			return false;
		}

		// 发布订单-保存订单信息到数据库
		saveOrderInfoService.saveOrderInfo(reqReleaseOrderDTO, response);

		return true;

	}

	/**
	 * @Title: billingConditions
	 * @Description: 发单条件
	 * @param reqReleaseOrderDTO
	 *            发布订单客户端传入参数
	 * @author YHQ
	 * @return boolean true:符合发单条件 false:不符合发布订单条件
	 */
	public boolean billingConditions(ReqReleaseOrderDTO reqReleaseOrderDTO, ResponseEntity<ResReleaseOrder> response) {

		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqReleaseOrderDTO, ReqReleaseOrderDTO.class);

		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(PublishOrderCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;

		}

		/**
		 * 判断客户端传入参数是否合理（订单出发时间是否合理，出发时间不能早于系统当前时间，并且不能大于超过系统当前时间48小时）
		 */
		if (DateFormatUtil.isClientTimeNotTrue(reqReleaseOrderDTO.getSetOutTime())) {

			response.setCode(SystemCode.SET_OUT_TIME_ERROR);// 230
			response.setErrorMessage(SystemCode.SET_OUT_TIME_MESSAGE);// 您的发单时间有误
			response.setPromptMessage(SystemCode.SET_OUT_TIME_MESSAGE);// 您的发单时间有误
			log.error("发单时间不合理!时间为：" + reqReleaseOrderDTO.getSetOutTime());
			return false;
		}

		// 判断是否存在未完成订单
		List<Userordert> userorderts = getUserOrders(reqReleaseOrderDTO.getPlaceOrderUserId(),
				reqReleaseOrderDTO.getIsLongDistance());

		if (userorderts != null && userorderts.size() > 0) {

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.NOT_COMPLETED_ORDER_MESSAGE);// 您尚有未完成订单，请先完成！
			response.setPromptMessage(PublishOrderCodeMsg.NOT_COMPLETED_ORDER_MESSAGE);
			log.error("有未完成订单，用户为：" + reqReleaseOrderDTO.getPlaceOrderUserId());
			return false;
		}

		// 获取用户登录信息
		UserLogin userLogin = userLoginFacade.getUserLoginInfo(reqReleaseOrderDTO.getPlaceOrderUserId());

		if (userLogin == null) {
			response.setCode(HttpStatus.SC_FORBIDDEN);// 230
			response.setErrorMessage(PublishOrderCodeMsg.USER_IS_NOT_EXIST);// 您的发单时间有误
			response.setPromptMessage(PublishOrderCodeMsg.USER_IS_NOT_EXIST);// 您的发单时间有误
			log.error("用户不存在:" + reqReleaseOrderDTO.getPlaceOrderUserId());
			return false;
		}

		// 获取当前用户的取消次数
		int cancelNumber = userLogin.getCancelNumber();
		// 获取当前用户的下单次数，如果超过5不能接单
		int publishNumber = userLogin.getPublishNumber();

		// 当天取消超过3次
		if (cancelNumber >= 3) {

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.CANCEL_ORDER_MUCH_MESSAGE);// 取消订单次数超过三次
			response.setPromptMessage(PublishOrderCodeMsg.CANCEL_ORDER_MUCH_MESSAGE);
			log.error("当天取消次数超过3次:" + reqReleaseOrderDTO.getPlaceOrderUserId());
			return false;
		}
		// 当日接单超过5次
		if (publishNumber >= 5) {

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.PUBLISH_ORDER_TOO_MUCH_MESSAGE);// 接单次数超过五次
			response.setPromptMessage(PublishOrderCodeMsg.PUBLISH_ORDER_TOO_MUCH_MESSAGE);
			log.error("当天接单次数超过5次:" + reqReleaseOrderDTO.getPlaceOrderUserId());
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @Title: getUserOrders
	 * @Description: 获取用户未完成订单列表
	 * @param userId 用户Id
	 * @param isLongDistance 订单类型(1:普通订单  2:长途订单)
	 * @author YHQ
	 * @return List<Userordert> 返回类型
	 * 
	 */
	@Transactional(readOnly = true)
	public List<Userordert> getUserOrders(String userId, Integer isLongDistance) {

		// 创建用于存储未完成订单的对象
		List<Userordert> userorderts = null;

		// 添加获取用户未完成订单列表
		Criterion criterion = Restrictions.and(Restrictions.eq("placeOrderUserId", userId),
				Restrictions.eq("isLongDistance", isLongDistance));

		try {
			userorderts = publishOrderDao.queryCriteriaList(criterion);
		} catch (Exception e) {
			log.error("根据用户Id和订单类型（长途或短途）时出现异常    类：" + this.getClass() + " getUserOrders()", e);
		}

		return userorderts;
	}

}
